﻿ #region Disclaimer/Info
 
 /////////////////////////////////////////////////////////////////////////////////////////////////
 //
 //   File:		TraceUtils.cs
 //   Website:		http://dexterblogengine.com/
 //   Authors:		http://dexterblogengine.com/About.ashx
 //   Rev:		1
 //   Created:		19/01/2011
 //   Last edit:		19/01/2011
 //   License:		GNU Library General Public License (LGPL)
 // 
 //   For updated news and information please visit http://dexterblogengine.com/
 //   Dexter is hosted to Codeplex at http://dexterblogengine.codeplex.com
 //   For any question contact info@dexterblogengine.com
 //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 #endregion

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text.RegularExpressions;
using Dexter.Domain.Model;
using Dexter.Logger.Contracts;

namespace Dexter.Web.Utils {
	public class TraceUtils : ITraceUtils {
		static readonly Regex trackbackLinkRegex = new Regex ( "trackback:ping=\"([^\"]+)\"" , RegexOptions.IgnoreCase | RegexOptions.Compiled );
		static readonly Regex urlsRegex = new Regex ( @"(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&amp;:/~\+#]*[\w\-\@?^=%&amp;/~\+#])?" , RegexOptions.IgnoreCase | RegexOptions.Compiled );

		readonly IWebUtils webUtils;

		/// <summary>
		/// 	Initializes a new instance of the <see cref = "TraceUtils" /> class.
		/// </summary>
		/// <param name = "logger">The logger.</param>
		/// <param name = "webUtils">The web utils.</param>
		public TraceUtils ( ILogger logger , IWebUtils webUtils ) {
			this.webUtils = webUtils;
		}

		#region ITraceUtils Members

		public void SendPingBack ( Item item , Uri itemUrl ) {
			IEnumerable <Uri> items = GetUrlsFromContent ( item.FormattedBody );

			foreach ( Uri t in items ) {
				string pageContent = webUtils.DownloadWebPage ( t );

				if ( string.IsNullOrEmpty ( pageContent ) ) {
					continue;
				}

				webUtils.SendPingBack ( itemUrl , t );
			}
		}

		public void SendTrackBack ( Item item , Uri itemUrl ) {
			IEnumerable <Uri> items = GetUrlsFromContent ( item.FormattedBody );

			foreach ( Uri t in items ) {
				string pageContent = webUtils.DownloadWebPage ( t );

				if ( string.IsNullOrEmpty ( pageContent ) ) {
					continue;
				}

				Uri trackbackUrl = GetTrackBackUrlFromPage ( pageContent );

				if ( trackbackUrl != null ) {
					var trackBack = new TrackBackMessage ( item , trackbackUrl , itemUrl );
					webUtils.SendTrackBack ( trackBack );
				}
			}
		}

		public void Ping ( Uri itemUri , Uri targetUri  ) {
			webUtils.SendPingBack ( itemUri , targetUri );
		}

		#endregion

		static IEnumerable <Uri> GetUrlsFromContent ( string content ) {
			var urlsList = new Collection <Uri> ( );

			MatchCollection items = urlsRegex.Matches ( content );

			for ( int i = 0; i < items.Count; i++ ) {
				if ( items[ i ].ToString ( ).ToLower ( ).EndsWith ( ".jpg" ) ||
				     items[ i ].ToString ( ).ToLower ( ).EndsWith ( ".jpeg" ) ||
				     items[ i ].ToString ( ).ToLower ( ).EndsWith ( ".gif" ) ||
				     items[ i ].ToString ( ).ToLower ( ).EndsWith ( ".png" ) ||
				     items[ i ].ToString ( ).ToLower ( ).EndsWith ( ".swf" ) ||
				     items[ i ].ToString ( ).ToLower ( ).EndsWith ( ".flv" ) ) {
					continue;
				}

				//string url = items[i].Groups[1].ToString().Trim();
				Uri uri;

				if ( Uri.TryCreate ( items[ i ].ToString ( ) , UriKind.Absolute , out uri ) ) {
					urlsList.Add ( uri );
				}
			}

			return urlsList;
		}

		static Uri GetTrackBackUrlFromPage ( string input ) {
			string url = trackbackLinkRegex.Match ( input ).Groups[ 1 ].ToString ( ).Trim ( );
			Uri uri;

			if ( Uri.TryCreate ( url , UriKind.Absolute , out uri ) ) {
				return uri;
			}

			return null;
		}
	}
}
